package base.generic.demo01_method;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

/**
 * 1. 如果在需要泛型的地方没有传递泛型,那么默认类型就是 Object
 * 2. 类的泛型类型,可以限定内部方法或者方法返回值的类型
 * 3. ?作为泛型的通配符(代表任意类型),不能在创建对象时使用,只能作为方法的入参使用.
 * 4. 泛型没有继承概念的
 */
public class Client {

    /**
     * 不使用泛型可能会出现的错误
     */
    @Test
    public void testCase1(){
        Collection coll = new ArrayList();// 不使用泛型,默认类型就是Object
        coll.add("张三");
        coll.add(true);
        coll.add(10);

//        coll.forEach(x->{
//            //String s = (String)x;
//            System.out.println(x.length());
//        });
        Iterator iterator = coll.iterator();
        while (iterator.hasNext()){
            String next = (String)iterator.next();//true 和 10 不能转换为 String 类型
            System.out.println(next.length());
        }
    }


    @Test
    public void testCase2(){
        Generic gc = new Generic();//不使用泛型,默认是 Object 类型, 影响着方法setObje的入参类型,getObje的返回类型.
        gc.setObj("String");// 可以存储的类型是Object
        gc.setObj(10);

        //String str = gc.getObj();//不能将 Object类型转换为 String类型
        Object obj = gc.getObj();
        System.out.println(obj);


        Generic<String> gcc = new Generic<>();
        gcc.setObj("我是字符串");
//        gcc.setObj(10);//不能存储整型,由类的泛型限制住了方法入参的类型
        String str = gcc.getObj();
        System.out.println(str.length());//如果不使用泛型,就无法使用泛型的特定方法(这里指的是 String#length()),而只能使用 Object的方法.
    }

    @Test
    public void testCase3(){
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);

        List<String> list2 = new ArrayList<>();
        list2.add("aa");
        list2.add("bb");

        printArray(list1);
        printArray(list2);

//        List<?> list03 = new ArrayList<?>();//泛型不能在创建对象时使用
//        list03.add("String");
//        list03.add(new Object());
    }

//    public void printArray(List<Integer> list){
//    public void printArray(List<String> list){
//    public void printArray(List<Object> list){// 泛型没有继承概念的
    public void printArray(List<?> list){ //以上三种情况都不能满足 testCase3()方法的调用. ? 泛型通配符,代表任意类型.
        Iterator<?> iterator = list.iterator();
        while (iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
        }

        for (Object o : list) {
            System.out.println(o);
        }
    }
}

class Generic<E> {
    private E obj;
    public E getObj(){
        return obj;
    }
    public void setObj(E obj){
        this.obj = obj;
    }
}
